# CVS: $Id: OPT_EXT.pm,v 1.1 2007/10/08 09:26:03 schweitz Exp $
# Time-stamp: <18 Jan 02 12:32:05 giron1>

=head1 NAME

OPT_EXT - Optional extension coding package

=head1 SYNOPSIS

 use OPT_EXT;

 my $ext = $pkg->Cond2Ext(\@cond);
 my @cond = $pkg->Ext2Cond($ext);
 my @cond = $pkg->CompileCond($OptList,\@ARGV);
 ...

=head1 DESCRIPTION

The I<OPT_EXT> package implements the encoding and decoding of STC
features and speech files optional extension. This is used in
conjunction with the B<compile_cond.perl> program which returns
conditions files used by B<noise_mix> or with B<opt_ext.perl> which
provides encoding and decoding of such extensions.

=head1 SEE ALSO

STC Optional extension description:

L<Naming_Conventions>,

the programs:

L<optext>,
L<compile_cond>

=head1 AUTHOR

 $Id: OPT_EXT.pm,v 1.1 2007/10/08 09:26:03 schweitz Exp $
 Franck Giron

=head1 LOG

 $Log: OPT_EXT.pm,v $
 Revision 1.1  2007/10/08 09:26:03  schweitz
 version 2.4, lib vergessen

 Revision /main/7  19-Apr-2002.18:41:50  giron1
 Automatic definition of package added.
 
 Revision 1.6  2001/07/20 14:25:58  giron1
 Addition of keywords to DCL_AIBO_Noise package.
 Speech extension composed of two options now.

 Revision 1.5  2001/03/05 17:02:00  giron1
 some reorganisation of functions and debugging

 Revision 1.4  2000/04/27 17:20:13  giron1
 Pod documentation extended


=cut

package OPT_EXT;

my $MIC_TYPES = ['standard','array','cellular','navi','mu2c'];
# If you add a new package, define here its environment values accepted
my %PACKS_ENV_START = ('Clean'=> [0,0],
		       'DCL_Car_Noise' => [1,1023] ,
		       'STC_Car_Noise' => [1024,2047],
		       'DCL_AIBO_Noise' => [2048,4095]
		      );
my $PERL_UTIL_PATH = $ENV{COMMON_MMIV} . '/vobs/speech/perl/util/';

#----------------------------------------------------------------------
# perl packages
#----------------------------------------------------------------------
use strict;
use Misc;
#----------------------------------------------------------------------

=head1 FUNCTIONS

The following functions are available:

=head2 new

C<$pkg = new OPT_EXT $name;>

This function defines a new OPT_EXT package with the name given by
I<$name>. The variable I<$pkg-E<gt>{'name'}> is then used to access a
subpackage named by I<$name>. The variable I<$pkg-E<gt>{'data'}> contains
the corresponding newly created data depending from this subpackage.

=cut

#----------------------------------------------------------------------

sub new{
  my $that = shift;
  my ($pkgname) = @_;
  my $class = ref($that) || $that;
  my $self = {};
  $self->{'name'} = $pkgname;
  $self->{'data'} = $pkgname->new;
  bless $self, $class;
  return $self;
}

#----------------------------------------------------------------------

=head2 Cond2Ext

C<my $ext = $pkg-E<gt>Cond2Ext(\%Cond);>

This method returns the string I<$ext> corresponding to the ATCS
extension used for speech or features files. The way the method acts
is defined from each subpackage I<$pkg> defined below. The hash
I<%Cond> contains a description of conditions corresponding to a hierarchy
of environments defined also by the subpackage I<$pkg>. 

=cut

#----------------------------------------------------------------------

sub Cond2Ext {
  my $pkg = shift;
  my ($condref) = @_;

 
  # Read the different existing conditions from the 
  # noise database information file

  $pkg->GetCond;

  # Test if the condition asked is possible
  my $path = $pkg->{'data'}->{'Root'} . join('/',@{$condref->{'env'}});
  die "Error: $path not recorded yet...\n" if (not defined($pkg->{'data'}->{'infos'}{$path}));
 
  # Convert to string
  my $ext = $pkg->ToString($condref);

  return $ext;
}

#----------------------------------------------------------------------

=head2 Ext2Cond

C<my %Cond = $pkg-E<gt>Ext2Cond($ext);>

This is the opposite function which matches an extension I<$ext> with
the methods defined in I<$pkg> and returns the corresponding
conditions in a hash.

=cut

#----------------------------------------------------------------------

sub Ext2Cond {
  my $pkg = shift;
  my ($ext) = @_;

  # Test if the conditions are already defined.
  # If not, read the different existing conditions from the 
  # noise database information file

  $pkg->GetCond;

  # Convert the extension to a hash
  my %Cond = $pkg->ToCond($ext);

  return %Cond;
}

#----------------------------------------------------------------------

=head2 GetCond

C<$pkg-E<gt>GetCond;>

This method gets all possible conditions and database informations
from a file and stores the result in the fields I<infos> and
I<allcond> of I<$pkg-E<gt>{'data'}>.

=cut

#----------------------------------------------------------------------
sub GetCond {
  my $pkg = shift;

  # Reads database Noise infos
  $pkg->ReadNoiseInfos;

  # Test if the conditions hash is already defined.
  # If not extract all possible conditions
  if (not defined($pkg->{'data'}->{'allcond'})) {$pkg->Infos2Cond;}
}



#----------------------------------------------------------------------

=head2 GetVarCond

C<my @Variable_Cond = $pkg-E<gt>GetVarCond($optl,\%Cond);>

Get all possible variable conditions from the expected I<%Ccnd> hash
using the definitions in package I<$pkg> and the options I<$optl>.

The options which have to be defined are the following ones:

=over 10

=item $optl->{'enist'}{'string'}

The extension of the nist files.

=item $optl->{'spow'}{'string'}

The complete speech power file path.

=item $optl->{'sfreq'}{'string'}

The sampling frequency of the noisy file if it contains raw data.

=back

=cut

#----------------------------------------------------------------------

sub GetVarCond {
  my $pkg = shift;
  my ($optl,$condref) = @_;

  # Read the different existing conditions from the 
  # noise database information file

  $pkg->GetCond;

  $optl->{'debug'}{'Do'} and warn "GetVarCond: ",join(' ',%$condref),"\n";

  my $path = join('/',@{$condref->{'env'}});

  # substitute all + in the resulting path which makes problem with matching
  # and replaces // with \.* to search all possible directories
  my $pattern = $path; $pattern =~ s/(\+)/\\$1/g; $pattern =~ s/\/\//\.*/g;

  $optl->{'debug'}{'Do'} and warn "GetVarCond: $pattern\n";

  # find the corresponding paths which match the pattern
  my @res = grep m/$pattern/, keys %{$pkg->{'data'}->{'infos'}};

  ($#res lt 0) && die "Sorry, $path not existent now. Check your noisy conditions.\n";

  my @condarr = ();
  my $efreq = '';
  foreach (@res) {
    my $val = {};
    # store the speech path and extension values
    $val->{'VOICE_DIRECTORY'}    = $optl->{'din'}{'string'};
    $val->{'VOICE_EXTENSION'}    = $optl->{'ein'}{'string'};
    $val->{'VOICE_POWER_FILE'}   = $optl->{'pin'}{'string'};
    # store the noise related variables
    $val->{'NOISE_DIRECTORY'}    = $_;
    $val->{'NOISE_NAME'}         = $optl->{'nnoise'}{'string'};
    $val->{'NOISE_EXTENSION'}    = $optl->{'enoise'}{'string'};
    $val->{'NOISE_START_NUMBER'} = $pkg->{'data'}->{'infos'}{$_}{'S'};
    $val->{'NOISE_END_NUMBER'}   = $pkg->{'data'}->{'infos'}{$_}{'E'};
    $val->{'NOISE_SAMP_FREQ'}    = $optl->{'snoise'}{'string'};
    # store the output related variables
    $val->{'OUTPUT_DIRECTORY'}   = $optl->{'dout'}{'string'};
    # returns the coded environment extension
    my @condlist = split /\//,$_;
    my %Cond = ('env' => \@condlist, 'mic' => $condref->{'mic'}, 'sf' => $condref->{'sf'});
    $val->{'OPT_EXT'}            = $pkg->ToString(\%Cond);
    $val->{'OUTPUT_EXTENSION'}   = $val->{'OPT_EXT'} . $optl->{'eout'}{'string'};
    # dB value
    $val->{'DB_VALUE'}           = $pkg->{'data'}->{'infos'}{$_}{'SNR'};
    # Creates the path to power file
    s,wave,feat/power,;
    $val->{'NOISE_POWER_DIRECTORY'} = $_;
    
    push @condarr, $val;
  }
  return @condarr;
}

#----------------------------------------------------------------------

=head2 ReadCondFile

C<my @lines = $pkg-E<gt>ReadCondFile;>

returns all lines of the general conditions file defined by I<$pkg> in
the array I<@lines>.

=cut

#----------------------------------------------------------------------

sub ReadCondFile {
  my $pkg = shift;

  my @res = ();
  my $fh = new FileHandle $pkg->{'data'}->{'GEN_COND_FILE'}, 'r';
  while (<$fh>) { push @res, $_;}
  $fh->close;

  return @res;
}
#----------------------------------------------------------------------

=head2 CompileCond

C<my @condfilelist = $pkg-E<gt>CompileCond($optl,$cond_ref);>

compiles condition files from the conditions given in the array
referenced by I<$cond_ref> and the options given in I<$optl>.
The options which have to be defined are the following ones:

=over 5

=item $optl->{'cond'}{'string'} 

The basename of the condition file.

=item $optl->{'enist'}{'string'}

The extension of the nist files.

=item $optl->{'spow'}{'string'}

The complete speech power file path.

=item $optl->{'sfreq'}{'string'}

The sampling frequency of the noisy file if it contains raw data.

=back

=cut

#----------------------------------------------------------------------

sub CompileCond {
  my $pkg = shift;
  my ($optl,$condref) = @_;

  # Get all possible conditions
  my @Variable_Cond = $pkg->GetVarCond($optl,$condref);

  # Debug option
  if ($optl->{'debug'}{'Do'}) {
    my $ref;
    foreach $ref (@Variable_Cond) {
      warn "CompileCond: $ref->{'NOISE_DIRECTORY'}:\n";
      my @envlist = split '/', $ref->{'NOISE_DIRECTORY'};
      # take only the final part of the list up to the number of conditions
      splice @envlist, 0, $#envlist - $#{$condref->{'env'}};
      warn "CompileCond: $ref->{'OPT_EXT'}\t@envlist\n";
      my $ext = $ref->{'OPT_EXT'} . '.m' . $condref->{'mic'} . '.' .  $condref->{'sf'} . 'k';
      my @decoded = $pkg->Ext2Cond($ext);
      warn "CompileCond: \t\t@decoded\n";
    }
  }

  # Read the general conditions in a lines array
  my @lines = $pkg->ReadCondFile;

  # Replace variables with correct values in condition files
  my $pattern = join ('|', keys %{$Variable_Cond[0]});
  $optl->{'debug'}{'Do'} and warn "CompileCond: pattern = $pattern\n";

  # Open output condition file and replace the right value for each
  # variable condition

  my $varcond;
  my @condfilelist = ();
  foreach $varcond (@Variable_Cond) {
    my $fileout =  $optl->{'cond'}{'string'} . $varcond->{'OUTPUT_EXTENSION'} . '.txt';
    $optl->{'debug'}{'Do'} and warn "CompileCond: > $fileout \n";
    my $fho = new FileHandle $fileout, 'w';
    foreach (@lines) {
      if (m/\$($pattern)/) { 
	my $val = $1;
	$optl->{'debug'}{'Do'} and warn "$val: $varcond->{$val}\n";
	s/\$$val/$varcond->{$val}/; 
      }
      print $fho $_;
    }
    $fho->close;
    push @condfilelist, $fileout;
  }

  return @condfilelist;
}
#----------------------------------------------------------------------

=head2 Infos2Cond

C<$pkg-E<gt>Infos2Cond;>

extracts the different possible conditions from a directory listing
contained in I<%infos> given the subpackage I<$pkg> keys list. The
directory structure must be fixed.

=cut

#----------------------------------------------------------------------

sub Infos2Cond {
  my $pkg = shift;

  # Read the directories file and split it in its different part
  # from the subpackage keywords list
  foreach (keys %{$pkg->{'data'}->{'infos'}}) {
    s/$pkg->{'data'}->{'Root'}//;
    my @dirlst = split '/',$_;
    my $count = 0;
    foreach (@{$pkg->{'data'}->{'Conditions_Keys'}}) {
      push @{$pkg->{'data'}->{'allcond'}{$_}},$dirlst[$count];
      my @tsort = sort @{$pkg->{'data'}->{'allcond'}{$_}};
      my @tuni = uniq(@tsort);
      @{$pkg->{'data'}->{'allcond'}{$_}} = @tuni;
      $count++;
    }
  }

  # Debugging only
  my $debug = 0;
  if ($debug) {
    foreach (@{$pkg->{'data'}->{'Conditions_Keys'}}) {
      my $aref = $pkg->{'data'}->{'allcond'}{$_};
      warn "$_: @$aref ($#{$aref})\n";
    }
  }
}

#----------------------------------------------------------------------

=head2 ToString

C<my $string = $pkg-E<gt>ToString(\@cond);>

converts the condition array to a string.

=cut

#----------------------------------------------------------------------

sub ToString {
  my $that = shift;
  my $condref = shift;

  my @envlist = @{$condref->{'env'}};
  splice @envlist, 0, $#envlist - $#{$that->{'data'}->{'Conditions_Keys'}};

  my $env = $that->{'data'}->{'Env_Start'};

  my $ind=0;
  my $indexmic=undef;
  foreach my $key (@{$that->{'data'}->{'Conditions_Keys'}}) {
    my $val = $envlist[$ind];
    # microphone coded in the path
    if ($key eq 'mic') {
    LOOP: for ($indexmic=0; $indexmic<$#{$MIC_TYPES}; $indexmic++) {
	last LOOP if ($MIC_TYPES->[$indexmic] =~ m/$val/);
      }
    }
    else {
      $env += $that->CodeEnv($key,$val);
    }
    $ind++;
  }
  my $res = sprintf ".e%d",$env;
  
  my $emic;
  # microphone extension part defined from path and also externally
  if (defined $indexmic and defined $condref->{'mic'}) {
    # check the identity
    if ($indexmic == $condref->{'mic'}) {$emic = $indexmic;}
    # if not, send a warning message and take the externally defined one
    else {
      $emic = $condref->{'mic'};
      warn "!!! WARNING: path microphone: $MIC_TYPES->[$indexmic] not equal to given number: $condref->{'mic'}\n";
      warn "check your output extension in the condition file coded now as : .m$emic\n";
    }
  }
  # microphone extension part defined from path
  elsif (defined $indexmic and not defined $condref->{'mic'}) {$emic = $indexmic;}
  # microphone extension defined externally
  elsif (not defined $indexmic and defined $condref->{'mic'}) {$emic = $condref->{'mic'};}
  # microphone extension not defined at all
  else {$emic = undef;}

  # extend the extension with the microphone one if defined
  if (defined $emic) {
    $res .= sprintf ".m%d",$emic;
  }

  # sampling frequency extension part
  if (defined $condref->{'sf'}) {
    $res .= sprintf ".%dk",$condref->{'sf'};
  }

  return $res;
}
#----------------------------------------------------------------------

=head2 ToCond

C<my @list = $pkg-E<gt>ToCond($ext);>

converts the string I<$ext> to the condition list I<@list> using the
conditions defined by the package I<$pkg>.

=cut

#----------------------------------------------------------------------

sub ToCond {
  my $that = shift;
  my $string = shift;

  my %cond = ('env' => undef, 'mic' => undef, 'sf' => undef);
  my @envlist = ();

  warn "ToCond: string = $string\n";

  # search for predefined parameters
#  $string =~ m/e(\d+)\.?m?(\d+)?\.?(\d+)?k?/;
  $_ = $string;
  my $env = undef
  my $mic = undef;
  my $sf  = undef;
  # environment number
  if (m/\.?e(\d+)/) {
    $env = $1-$that->{'data'}->{'Env_Start'};
    warn "ToCond: env = $env\n";
  }
  else {warn "ToCond: environment extension not defined !\n";}
  # microphone number
  if (m/\.?m(\d+)/) {
    $mic = $1;
    $cond{'mic'} = $mic;
    warn "ToCond: mic = $mic\n";
  }
  else {warn "ToCond: microphone extension not defined !\n";}
  # sampling frequency
  if (m/\.(\d+)k/) {
    $sf = $1;
    $cond{'sf'} = $sf;
    warn "ToCond: sf = $sf\n";
  }
  else {warn "ToCond: sampling frequency extension not defined !\n";}

  my ($key,$val);
  foreach $key (@{$that->{'data'}->{'Conditions_Keys'}}) {
    if ($key eq 'mic') {
      if (defined($mic) and $mic >= 0 and $mic <= $#{$MIC_TYPES}) {
	$val = $MIC_TYPES->[$mic];
      }
      else {
	warn "ToCond: microphone not defined !\n";
	$val = 'undef';
      }
    }
    else {
      $val = $that->DecodeEnv($key,$env);
      warn "ToCond: $val\n";
    }
    push @envlist,$val;
  }

  $cond{'env'} = \@envlist;
  warn "ToCond: @{$cond{'env'}}\n";
  return %cond;
}
#----------------------------------------------------------------------

=head2 CodeEnv

C<$env = $pkg-E<gt>CodeEnv($key,$val);>

this is the heart of the encoding. It converts the value I<$val> to
the integer value I<$env> according to its position in the conditions
array defined by I<$pkg> and the key I<$key>.

=cut

#----------------------------------------------------------------------

sub CodeEnv {
  my $that = shift;
  my ($key,$val) = @_;

  my $v = 0;
  foreach (@{$that->{'data'}->{'allcond'}->{$key}}) {
    last if ($val eq $_);
    $v++;
  }
  $v = $v << $that->{'data'}->{'shiftbits'}{$key};
  return $v;
}

#----------------------------------------------------------------------

=head2 DecodeEnv

C<$val = $pkg-E<gt>DecodeEnv($key,$env);>

This is the heart of the decoding. It proceeds the other way round of
the preceding algorithm.

=cut

#----------------------------------------------------------------------

sub DecodeEnv {
  my $that = shift;
  my ($key,$val) = @_;

  my $ind = ($val & hex($that->{'data'}->{'maskbits'}{$key})) >> $that->{'data'}->{'shiftbits'}{$key};
  if ($ind >= 0 and $ind <= $#{$that->{'data'}->{'allcond'}->{$key}}) {
    return $that->{'data'}->{'allcond'}->{$key}[$ind];
  }
  else {return 'undef';}
}

#----------------------------------------------------------------------

=head2 ReadNoiseInfos

C<$pkg-E<gt>ReadNoiseInfos;>

reads a noise conditions file containing noise directory followed by
start and end noise numbers as well as dB values. The noise
directories serves as key for further informations.

=cut

#----------------------------------------------------------------------

sub ReadNoiseInfos {
  my $pkg = shift;

  my ($dir);

  my $fh = new FileHandle $pkg->{'data'}->{'Noise_Infos'}, 'r';
  while (<$fh>) {
    next if (m/^$/);
    chop;
    my ($st,$val) = split /\:\s+/,$_;
  SWITCH: {
      if ($st =~ m/^Data/) {$dir = $val; last SWITCH; }
      if ($st =~ m/^Start/) {$pkg->{'data'}->{'infos'}{$dir}{'S'} = $val; last SWITCH; }
      if ($st =~ m/^End/) {$pkg->{'data'}->{'infos'}{$dir}{'E'} = $val; last SWITCH; }
      if ($st =~ m/^SNR/) {$pkg->{'data'}->{'infos'}{$dir}{'SNR'} = $val; last SWITCH; }
    }
  }
  $fh->close;
}

#----------------------------------------------------------------------

=head2 GetPackage

C<$pkg-E<gt>GetPackages($env);>

returns the package name corresponding to the value of the environment
given by I<$env>

=cut


sub GetPackage {
  my $env = shift;

  my ($key,$value);
  $key = undef;
  while (($key,$value) = each %PACKS_ENV_START) {
    last if ( @$value[0] <= $env and  $env <= @$value[1])
  }
  if (defined $key) {warn "using package: $key = e@$value[0] - e@$value[1]\n";}
  return $key;
}

#----------------------------------------------------------------------

=head1 SUB-PACKAGES

Here starts the definition of special packages for the preceding
functions:

=head2 DCL_Car_Noise

It contains the necessary functions for the encoding of the car noise
database recorded at DCL. The conditions which have been defined are given 
by the I<@Conditions_Keys> keys list.

=cut

package DCL_Car_Noise;

# perl packages

use FileHandle;

#  Global Variables
my $DCL_Car_Noise_Conditions_Keys = ['car','type','mic','env','road'];
# start bit of particular environment
my %DCL_Car_Noise_shiftbits = ('car' => 0, 'road' => 4, 'env' => 7, 'type' => 9);
# hexadecimal mask values
my %DCL_Car_Noise_maskbits = ('car' => 'F', 'road' => '70', 'env' => '180', 'type' => '200');
my $DCL_Car_Noise_Root = '/speech/db/jpn/data/recog/db/wave/noise/car/';
my $DCL_Car_Noise_Noise_Infos = $PERL_UTIL_PATH . 'DCL_Car_Noise_Infos.txt';
my $DCL_Car_Noise_GEN_COND_FILE = $PERL_UTIL_PATH . 'Noise_General_Condition.txt';

#----------------------------------------------------------------------
# Functions
#----------------------------------------------------------------------

=over 8

The following functions are available for this package:

=item C<$pkg = new DCL_Car_noise;>

This function defines a new DCL_Car_Noise environment.

=back

=cut

#----------------------------------------------------------------------

sub new{
  my $that = shift;
  my $class = ref($that) || $that;
  my $self = {};
  $self->{'Conditions_Keys'} = $DCL_Car_Noise_Conditions_Keys;
  $self->{'shiftbits'} = \%DCL_Car_Noise_shiftbits;
  $self->{'maskbits'} = \%DCL_Car_Noise_maskbits;
  $self->{'Root'} = $DCL_Car_Noise_Root;
  $self->{'Noise_Infos'} = $DCL_Car_Noise_Noise_Infos;
  # Start value added to the environment category number
  $self->{'Env_Start'}= $PACKS_ENV_START{'DCL_Car_Noise'}[0];
  $self->{'GEN_COND_FILE'} = $DCL_Car_Noise_GEN_COND_FILE;
  bless $self, $class;
  return $self;
}

#----------------------------------------------------------------------

=head2 STC_Car_Noise

This subpackage contains the necessary functions for the encoding of
the car noise database recorded at STC. The conditions which have been
predefined here are given by the I<@Conditions_Keys> keys list. All
possible conditions are defined here in this package. For possible
extensions a file solution would be preferable.

=cut

#----------------------------------------------------------------------

package STC_Car_Noise;

# perl packages

use FileHandle;

#  Global Variables
my $STC_Car_Noise_Conditions_Keys = ['car','type','mic','env','road'];
# start bit of particular environment
my %STC_Car_Noise_shiftbits = ('car' => 0, 'road' => 4, 'env' => 7, 'type' => 9);
# hexadecimal mask values
my %STC_Car_Noise_maskbits = ('car' => 'F', 'road' => '70', 'env' => '180', 'type' => '200');
my $STC_Car_Noise_Root = '/speech/db/deu/noise/car/';
my $STC_Car_Noise_Noise_Infos = $PERL_UTIL_PATH . 'STC_Car_Noise_Infos.txt';
my $STC_Car_Noise_GEN_COND_FILE = $PERL_UTIL_PATH . 'Noise_General_Condition.txt';
# Predefined car noise conditions. If the number of noise conditions increases
# the solution of reading the data automatically from a file should be choosen
my %STC_Car_Noise_allcond = ('car'  => [qw(bmw316i bmw318d)],
			     'road' => [qw(hiway idle_n idle_s midway town '' '' mixed)],
			     'env'  => [qw(fine fine+music rain rain+music)],
			     'type' => ['ge','st']);

#----------------------------------------------------------------------
# Functions
#----------------------------------------------------------------------

=over 8

The following functions are available for this package:

=item C<$pkg = new STC_Car_Noise;>

This function defines a new STC_Car_Noise environment.

=back

=cut

#----------------------------------------------------------------------

sub new{
  my $that = shift;
  my $class = ref($that) || $that;
  my $self = {};
  $self->{'Conditions_Keys'} = $STC_Car_Noise_Conditions_Keys;
  $self->{'shiftbits'} = \%STC_Car_Noise_shiftbits;
  $self->{'maskbits'} = \%STC_Car_Noise_maskbits;
  $self->{'Root'} = $STC_Car_Noise_Root;
  $self->{'Noise_Infos'} = $STC_Car_Noise_Noise_Infos;
  # Start value added to the environment category number
  $self->{'Env_Start'}= $PACKS_ENV_START{'STC_Car_Noise'}[0];
  $self->{'GEN_COND_FILE'} = $STC_Car_Noise_GEN_COND_FILE;
  $self->{'allcond'} = \%STC_Car_Noise_allcond;
  bless $self, $class;
  return $self;
}
#----------------------------------------------------------------------

=head2 DCL_AIBO_Noise

This subpackage contains the necessary functions for the encoding of
the aibo noise database recorded at DCL. The conditions which have been
predefined here are given by the I<@Conditions_Keys> keys list. All
possible conditions are defined here in this package. For possible
extensions a file solution would be preferable.

=cut

#----------------------------------------------------------------------

package DCL_AIBO_Noise;

# perl packages

use FileHandle;

#  Global Variables
my $DCL_AIBO_Noise_Conditions_Keys = ['name','type'];
# start bit of particular environment
my %DCL_AIBO_Noise_shiftbits = ('name' => 0, 'type' => 5);
# hexadecimal mask values
my %DCL_AIBO_Noise_maskbits = ('name' => '1F', 'type' => '3e0');
my $DCL_AIBO_Noise_Root = '/speech/db/jpn/data/recog/db/wave/noise-16k/aibo/';
my $DCL_AIBO_Noise_Noise_Infos = $PERL_UTIL_PATH . 'DCL_AIBO_Noise_Infos.txt';
my $DCL_AIBO_Noise_GEN_COND_FILE = $PERL_UTIL_PATH . 'Noise_General_Condition.txt';
# Predefined car noise conditions. If the number of noise conditions increases
# the solution of reading the data automatically from a file should be choosen
my %DCL_AIBO_Noise_allcond = ('name' => [qw(pink servo white conf)],
			      'type' => [qw(param_003 param_011 left mix right std)]);

#----------------------------------------------------------------------
# Functions
#----------------------------------------------------------------------

=over 8

The following functions are available for this package:

=item C<$pkg = new DCL_AIBO_Noise;>

This function defines a new DCL_AIBO_Noise environment.

=back

=cut

#----------------------------------------------------------------------

sub new{
  my $that = shift;
  my $class = ref($that) || $that;
  my $self = {};
  $self->{'Conditions_Keys'} = $DCL_AIBO_Noise_Conditions_Keys;
  $self->{'shiftbits'} = \%DCL_AIBO_Noise_shiftbits;
  $self->{'maskbits'} = \%DCL_AIBO_Noise_maskbits;
  $self->{'Root'} = $DCL_AIBO_Noise_Root;
  $self->{'Noise_Infos'} = $DCL_AIBO_Noise_Noise_Infos;
  # Start value added to the environment category number
  $self->{'Env_Start'}= $PACKS_ENV_START{'DCL_AIBO_Noise'}[0];
  $self->{'GEN_COND_FILE'} = $DCL_AIBO_Noise_GEN_COND_FILE;
  $self->{'allcond'} = \%DCL_AIBO_Noise_allcond;
  bless $self, $class;
  return $self;
}
1;

__END__

